iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0
ChatGPT & Codex

當 Codex 開始自己工作:從 Prompt Engineering 到 Agent Governance系列 第 5

Day 5|DECISIONS.md:不要讓下一個 Session 把已否決方案重新發明一次

  • 分享至 

  • xImage
  •  

Day 5

Day 4 留下了一個問題。

PROJECT_STATE.md 可以告訴新的 Agent:

這個專案現在在哪裡。

例如:

目前採用方案 B
backend 已完成
frontend 尚未開始
migration 不需要
production 尚未 deploy

這已經比每次重新掃 Repository 好很多。

但新的 Session 讀完之後,還是很可能問:

為什麼採用 B?

甚至更進一步:

我分析了一下,A 好像更簡單,要不要改用 A?

問題是——

A 可能三天前就已經分析過,而且明確否決了。

如果當時只留下最後結果:

採用 B

卻沒有留下:

為什麼不用 A

下一個 Agent 就很容易把同一個問題重新研究一次。

這也是 DECISIONS.md 值得從一般文件裡獨立出來的原因。


我遇到的不是「忘記答案」,而是「忘記推理結果」

最近整理鐵人賽 Repository 時,就碰到一個很典型的例子。

這個 Repo 裡同時有兩條系列:

bento-system
codex-workflow

一個方向是:

要不要乾脆把兩條系列整合成同一條主線?

表面上不是沒有道理。

便當系統本來就是 AI Coding 的真實案例,而 Codex 系列則整理這些專案逐步長出來的 Workflow。

如果新的 Agent 只看到現在的目錄,很可能再次提出:

Bento
   ↓
真實案例
   ↓
Codex Workflow
   ↓
合成同一套 30 天系列?

但這件事情其實已經討論過。

最後的決策是:

不合併。

原因也不是單純「我比較喜歡分開」。

而是兩條系列回答的問題不同:

Bento
→ 真實系統為什麼被迫演進?

Codex
→ Agent Workflow 為什麼被迫形成?

它們可以互相引用。

但如果合併:

  • Bento 很容易變成 Agent Governance 的案例集
  • Codex 又可能失去自己的問題意識
  • 兩條 30 天主線會互相綁死
  • 後面的 roadmap 會越來越難調整

Repository 裡留下的不只是:

兩個系列分開。

還有:

為什麼分開。
哪些方向已否決。
未來什麼情況下仍然不能重新合併。

這就是 Decision Record 跟 Project State 最大的差異。


State 保存「現在是什麼」,Decision 保存「為什麼變成這樣」

實務上可以刻意把這兩種資訊拆開。

PROJECT_STATE.md

目前有效狀態:
- Bento 與 Codex 是兩條獨立系列
- Day 1–4 已完成
- Day 5–30 繼續依各自 roadmap 前進

而:

DECISIONS.md

決策:
- Bento 與 Codex 不合併

原因:
- 兩邊回答不同問題
- 各自需要獨立 roadmap
- 可以交叉引用,但不能互相降格成附屬案例

前者告訴 Agent:

現在是什麼。

後者告訴 Agent:

為什麼會變成現在這樣。

少了後面這一層,Agent 很容易看到一個既有設計,卻把它誤認成:

「以前的人只是剛好這樣做。」

然後重新開始最佳化。


Agent 很擅長提出「看起來更好的方案」

這是一個有點反直覺的問題。

我們通常希望 Agent:

  • 主動分析
  • 找替代方案
  • 挑戰既有設計
  • 提出更簡單的做法

這些能力本身都很好。

但在長期專案裡,也因此會出現另一種成本:

Session A
分析 A / B / C
↓
否決 A
否決 C
↓
採用 B

Session B
不知道前面的理由
↓
重新分析 A / B / C
↓
「我建議 A」

這不一定是 Agent 判斷錯。

它可能真的有充分理由提出 A。

問題是:

它缺少的是過去已經付過的決策成本。

於是每次 Context 消失之後,同一筆成本又被付一次。


我想保存的是「被否決的理由」

一份 Decision Record 最有價值的內容,往往不是:

我們選 B。

而是:

A 為什麼沒有選?
B 為什麼目前成立?
C 在什麼條件下才值得重新考慮?

例如可以長成:

## Decision: Bento / Codex 維持兩條獨立系列

### Status
Accepted

### Context
兩條系列使用部分相同真實案例,
但閱讀目的與核心問題不同。

### Decision
維持獨立品牌、獨立 roadmap、獨立問題意識。

### Rejected alternative
合併成一條系列。

### Why rejected
- Bento 會失去真實系統演進主線
- Codex 會變成附屬方法論
- 後續 roadmap 容易互相綁定

### Revisit when
若未來兩條系列的核心問題本身發生改變,再重新評估。

這裡最值得保留的是:

Rejected alternative
Why rejected

因為最後答案通常很容易從目前 Repository 推回來。

最容易遺失的,是當初為什麼沒有走另外一條路。


不是每件小事都需要寫進 DECISIONS.md

但這也很容易走向另一個極端。

假設每一次開發都留下:

今天按鈕改藍色
今天 variable 改名
今天這個 function 拆成兩個
今天測試多加一個 case

DECISIONS.md 很快又會變成另一份 CHANGELOG。

我會先問:

下一個 Agent 如果不知道這件事,會不會很合理地重新做一次同樣的分析?

如果答案是會,才比較值得留下來。

例如:

適合記錄
────────────────────────
架構選擇
資料 authority
身份模型
migration 策略
安全邊界
被否決的重要方案
系列定位
重大 workflow 規則

通常不用記錄
────────────────────────
一般 refactor
單純 bug fix
variable rename
小型 UI 調整
很容易從 code 看出的實作細節

Decision Record 的目的不是建立完整歷史。

而是保存:

未來重新判斷時最昂貴的那部分 Context。


一個 Decision 至少要留下四件事

如果把格式壓到最小,至少需要:

CONTEXT
為什麼會需要做這個決定?

DECISION
最後選了什麼?

REJECTED
哪些重要替代方案沒有選?

RATIONALE
為什麼?

也就是:

問題
↓
選擇
↓
放棄什麼
↓
理由

這已經足以讓下一個 Session 少做大量重複探索。

如果決策有可能因環境改變而失效,還可以再補:

REVISIT WHEN
什麼條件出現時,允許重新打開這個決策?

這一欄很重要。

因為:

保存 Decision,不代表禁止未來改變 Decision。

它只是要求:

如果要推翻,至少先知道自己正在推翻什麼,以及當初為什麼這樣選。


Accepted 不應該等於「永遠不能碰」

這是 Decision Record 很容易被誤用的地方。

如果文件最後變成:

這件事以前決定過。
禁止討論。

那它就從 Durable Context 變成教條了。

真實軟體專案的條件會改變:

  • 使用者規模改變
  • 技術限制消失
  • 新 API 出現
  • 原本昂貴的方案變便宜
  • 新的 security requirement 出現
  • 原本假設被 Production 推翻

比較合理的狀態不是:

Accepted = 永久正確

而是:

Accepted
= 在當時 Context 與 Evidence 下,
  目前採用的決策

如果條件改變,就可以重新評估。

但新的分析應該建立在舊 Decision 上,而不是假裝它從未存在。


DECISIONS.md 也不是聊天紀錄

另一個重要邊界是:

不要把完整討論貼進去。

例如我們可能花了一個小時討論:

A 怎樣
B 怎樣
C 怎樣
A 的變形版本
B 再改一下
另外一個想法
最後又回來 B

這些探索過程對當下有價值。

但下一個 Agent 通常不需要一萬字聊天紀錄。

而是:

Context
Decision
Rejected Alternatives
Rationale
Revisit Condition

聊天適合探索。

Decision Record 適合把探索結果壓縮成:

未來還值得保留的判斷。

這也是後來逐漸固定下來的流程:

Conversation
      ↓
大量探索
      ↓
收斂
      ↓
DECISIONS.md

不是讓 Agent 永遠記得所有對話。

而是讓 Repository 記得那些:

忘掉之後會再次付出代價的東西。


到這裡,Context 開始分成三層

走到 Day 5,可以把前面幾天的東西理解成:

AGENTS.md
↓
怎麼工作

PROJECT_STATE.md
↓
現在在哪

DECISIONS.md
↓
為什麼走到這

這三份東西都在處理 Context。

但它們不是同一種 Context。

如果混在一起:

AGENTS.md
├─ 工作規則
├─ 目前進度
├─ 去年架構決策
├─ Bug 歷史
├─ 否決方案
└─ 下一步

最後 Agent 雖然「看得到很多」,

卻更難判斷:

什麼資訊現在最重要。

Durable Context 的重點,也慢慢不再是:

多放一些 Markdown。

而是:

讓不同類型的資訊,有明確的保存責任。


目前採用的 Decision Gate

現在遇到一個值得討論的決策時,可以先用這幾個問題判斷要不要留下:

1. 這個選擇未來很可能再次被提出嗎?

2. 重新分析它的成本高嗎?

3. Code 本身能清楚解釋為什麼這樣做嗎?

4. 有重要替代方案被刻意否決嗎?

5. 如果條件改變,是否需要知道什麼時候能重新評估?

判斷規則可以再簡化成一句:

如果一個決策未來很可能被重新提出,而且重新分析的成本不低,或其中有重要方案是「刻意否決」的,就值得留下 Decision Record。

目的不是把文件補得更完整。

目的是讓下一個 Agent:

不要從零開始思考一個其實已經思考過的問題。


到這裡的理解

DECISIONS.md 最大的價值,不是建立一份漂亮的決策文件。

而是讓 Repository 保存一種平常很容易消失的 Context:

我們為什麼沒有走那條路。

因為 Agent 換 Session 之後,風險不一定來自完全忘記。

更常見的是:

它重新做出一個新的、看起來也很合理的判斷。

如果舊方案曾經評估過、某個限制仍然存在、某條路也已經因為特定原因被否決,那些資訊就應該有地方被下一個 Agent 讀到。

這樣新的分析才能建立在舊 Decision 上,而不是每次從零開始。


下一篇

現在 Repository 已經可以保存:

怎麼工作
現在在哪
為什麼走到這

但大型任務真正跨 Session 時,還會有一個更短期、更實際的問題:

上一輪到底做到哪裡,下一輪第一步要接什麼?

這種資訊如果全部丟進 PROJECT_STATE.md,它很快就會被 Session 細節塞滿。

如果只留在聊天裡,換一輪又可能消失。

下一步,我會把焦點放到:

Session 結束之前,到底應該留下哪些資訊,才算一次真的能接手的 Handoff?


上一篇
Day 4|規則記住了,但「現在做到哪」誰來記?把專案狀態留在 Repository
下一篇
Day 6|Handoff 不是聊天摘要:一個 Agent Session 結束前真正該留下什麼
系列文
當 Codex 開始自己工作:從 Prompt Engineering 到 Agent Governance9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言